package com.loozb.fork;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.RecursiveTask;

/**
 * 计算从1+2+3+.......+1000+....+2000 = ？
 * Created by chuan on 2019-4-12.
 */
public class RecursiveTaskDemo extends RecursiveTask<Integer> {

    private static final int MAX = 80;//最多只计算50个

    private static int threadNUM = 400;//分成3个线程
    private int start;
    private int end;

    public RecursiveTaskDemo(int start, int end) {
        this.start = start;
        this.end = end;

//        if(end > MAX) {
//            threadNUM = end / 80;
//        }
    }

    /**
     * The main computation performed by this task.
     *
     * @return the result of the computation
     */
    @Override
    protected Integer compute() {
        int sum = 0;
        if((end - start) < MAX) {
            for (int i = start; i <= end; i++) {
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                sum += i;
            }
        } else {
            int step = (end + start) / threadNUM; //比如计算(1+11)/3 = 4，3个线程分别计算1+2+3+4和5+6+7+8和9+10+11
            List<RecursiveTaskDemo> recursiveTaskDemoList = new ArrayList<>();
            int pos = start; //init value = 1;
            for(int k = 0; k < threadNUM; k++) {
                int last = pos + step;  // 此时last=1+4=5，循环1-5，计算1+2+3+4
                if(last > end) last = end;
                RecursiveTaskDemo recursiveTaskDemo = new RecursiveTaskDemo(pos, last);
                recursiveTaskDemoList.add(recursiveTaskDemo);
                //开辟线程
                recursiveTaskDemo.fork();
                pos = last + 1;
            }

            for(RecursiveTaskDemo o : recursiveTaskDemoList) {
                sum += o.join();
            }
        }
        return sum;
    }

    public static void main(String[] args) {
        ForkJoinPool forkJoinPool = new ForkJoinPool();
        long start = System.currentTimeMillis();
        Integer integer = forkJoinPool.invoke(new RecursiveTaskDemo(1, 1000));
        long end = System.currentTimeMillis();
        long time = end - start;
        System.out.println("计算结果：" + integer + ",计算时间：" + time);


//        int sum = 0;
//        long start = System.currentTimeMillis();
//        for (int i = 1; i <= 1000; i++) {
//            try {
//                Thread.sleep(10);
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//            }
//            sum += i;
//        }
//        long end = System.currentTimeMillis();
//        long time = end - start;
//        System.out.println("计算结果：" + sum + ",计算时间：" + time);

    }
}
